/*
使用boost::beast库实现一个简单的HTTP服务器。  半成品
原文链接：https://llfc.club/articlepage?id=2RlhDCg4eedYme46C6ddo4cKcFN

HTTP请求包头：

GET /index.html HTTP/1.1
Host: www.example.com
Accept: text/html, application/xhtml+xml
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0
Cookie: sessionid=abcdefg1234567
Connection: keep-alive

Request-line：包含用于描述请求类型、要访问的资源以及所使用的HTTP版本的信息。
    Method：指定请求的方法，如GET(一般只有url)、POST(额外带有数据)等。
    Request-URL：指定请求的资源，如/index.html（根目录下的index.html文件）。
    HTTP：指定使用的协议和版本，如 HTTP/1.0。
Host：指定被请求资源的主机名或IP地址和端口号。
Accept：指定客户端能够接收的媒体类型列表，用逗号分隔，例如 text/plain, text/html。
User-Agent：客户端使用的浏览器类型和版本号，供服务器统计用户代理信息。
Cookie：如果请求中包含cookie信息，则通过这个字段将cookie信息发送给Web服务器。
Connection：表示是否需要持久连接（keep-alive：长连接）。


HTTP响应包头

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1024
Set-Cookie: sessionid=abcdefg1234567; HttpOnly; Path=/
Server: Apache/2.2.32 (Unix) mod_ssl/2.2.32 OpenSSL/1.0.1e-fips mod_bwlimited/1.4
Connection: keep-alive

Status-line：包含协议版本、状态码和状态消息。
Content-Type：响应体的MIME类型。
Content-Length：响应体的字节数。
Set-Cookie：服务器向客户端发送cookie信息时使用该字段。
Server：服务器类型和版本号。
Connection：表示是否需要保持长连接（keep-alive）。
*/


#ifndef HTTP_SERVER_H 
#define HTTP_SERVER_H 

#include "servlet.h"

#include <memory.h>
#include <string>
#include <ctime>

#include <boost/asio.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/asio/steady_timer.hpp>

class HttpConnection : public std::enable_shared_from_this<HttpConnection>
{
public:
    using ptr = std::shared_ptr<HttpConnection>;
    using TCP = boost::asio::ip::tcp;
    using RequestPtr = std::shared_ptr<boost::beast::http::request<boost::beast::http::dynamic_body>>;
    using ResponsePtr = std::shared_ptr<boost::beast::http::response<boost::beast::http::dynamic_body>>;
    using Buffer = boost::beast::flat_buffer;
    using Verb = boost::beast::http::verb;
    using Field = boost::beast::http::field;
    using Status = boost::beast::http::status;

	HttpConnection(TCP::socket socket);
	~HttpConnection();

    void Start();
    static void HttpAccept(TCP::acceptor& accept, TCP::socket& socket);

    //获取ServletDispatch
    ServletDispatch::ptr getServletDispatch() const { return m_dispatch;}

    //返回请求数
    static uint32_t RequestCount();
    //返回连接时间（当前时间）
    static std::time_t ConnectTime();

private:
    //判断定时器是否超时
    void _CheckTimeout();
    //接收请求
    void _ReadRequest();
    //处理请求
    void _ProcessRequest();
    //创建响应
    void CreateResponse();
    //发送响应
    void _WriteResponse();

private:
    TCP::socket m_socket;
    Buffer   m_buffer{8192};           //缓冲区
    RequestPtr  m_request;     //请求头部
    ResponsePtr m_response;    //响应头部
    ServletDispatch::ptr m_dispatch;    //Servlet分发器

    //第一个参数为调度器，这里指定为sock的调度器，第二个参数为超时时间
    boost::asio::steady_timer m_timer{m_socket.get_executor(), std::chrono::seconds{60}};
};


#endif	/* HTTP_SERVER_H */
